#include "../Base/stdafx.h"
#include "Bone.h"
#include "Skeleton.h"
#include "../Base/GameEngine.h"
#include <Boost/foreach.hpp>
#include "../Base/StringUtil.h"
#include "../xml/XmlLoader.h"
#include "../xml/XMLNode.h"
#include "Animation.h"


Skeleton::Skeleton( const tstring& file ): m_Speed(1)
{	
	XMLLoader xml(file);
	Bone* TempBone = NULL;
	TreeNode* parent = this;
	do 
	{
		if(xml.GetStartElement() == _T("bone"))
		{
			if(TempBone != NULL)
				m_Bones.insert(make_pair(TempBone->GetId(), TempBone));

			TempBone = new Bone(xml.GetValue(_T("name")), StringUtil::ToFloat(xml.GetValue(_T("length"))), StringUtil::ToInt(xml.GetValue(_T("id"))));
		}else if(xml.GetStartElement() == _T("pivot")){
			float x = StringUtil::ToFloat(xml.GetValue(_T("x")));
			float y = StringUtil::ToFloat(xml.GetValue(_T("y")));
			float z = StringUtil::ToFloat(xml.GetValue(_T("z")));
			TempBone->SetPivot(D3DXVECTOR3(x, y, z));
		}else if(xml.GetStartElement() == _T("transform")) {
			float tx = StringUtil::ToFloat(xml.GetValue(_T("tx")));
			float ty = StringUtil::ToFloat(xml.GetValue(_T("ty")));
			float tz = StringUtil::ToFloat(xml.GetValue(_T("tz")));
			float rx = StringUtil::ToFloat(xml.GetValue(_T("rx")));
			float ry = StringUtil::ToFloat(xml.GetValue(_T("ry")));
			float rz = StringUtil::ToFloat(xml.GetValue(_T("rz")));
			//TempBone->SetTranslate(D3DXVECTOR3(tx, ty, tz));
			TempBone->SetRotation(D3DXVECTOR3(rx, ry, rz));
			const XMLNode* par = xml.GetParent()->GetParent();
			//if(par->GetStartElem() == _T("skeleton"))
				TempBone->AddParent(this);
			//else
				//TempBone->AddParent(m_Bones.find(StringUtil::ToInt(par->GetValue(_T("id"))))->second);
			m_Bones.insert(make_pair(TempBone->GetId(), TempBone));
			TempBone = NULL;
		}
	} while (xml.Next());
}

Skeleton::~Skeleton()
{
	pair<int, Bone*> b;
	BOOST_FOREACH(b, m_Bones) delete b.second;
}

void Skeleton::Draw()
{
	pair<int, Bone*> b;
	BOOST_FOREACH(b, m_Bones) b.second->Draw();
}

void Skeleton::Init( const MeshDesc& mDesc )
{

}

void Skeleton::Tick( float dTime )
{
	pair<int, Bone*> b;
	static float totalTime = 0;
	totalTime += dTime;
	if(totalTime >= (1.0f/25)/m_Speed)
	{
		BOOST_FOREACH(b, m_Bones) b.second->NextStep();
		totalTime -= (1.0f/25)/m_Speed;
	}	
	BOOST_FOREACH(b, m_Bones) b.second->GetTotalTranspose();
}

void Skeleton::PlayAnimation( const Animation* anim )
{
	pair<int, Bone*> b;
	BOOST_FOREACH(b, m_Bones) b.second->SetAnimation(anim->GetAnim(b.first));
}

void Skeleton::SetSpeed( float speed )
{
	m_Speed = speed;
}

vector<D3DXMATRIX> Skeleton::GetBoneMatrix() const
{
	pair<int, Bone*> b;
	vector<D3DXMATRIX> temp;
	BOOST_FOREACH( b, m_Bones) temp.push_back(b.second->GetWorldMatrix());
	return temp;
}